package com.stock_t.utils;

import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * HTTP请求工具类
 */
@Slf4j
public class HttpUtils {

    /**
     * 默认超时时间（秒）
     */
    private static final int DEFAULT_TIMEOUT = 10;
    
    /**
     * 默认内容类型
     */
    private static final String DEFAULT_CONTENT_TYPE = "application/json; charset=utf-8";
    
    /**
     * 媒体类型 - JSON
     */
    private static final MediaType JSON = MediaType.parse(DEFAULT_CONTENT_TYPE);
    
    /**
     * 单例OkHttpClient
     */
    private static OkHttpClient client;
    
    /**
     * 获取OkHttpClient实例
     * 
     * @param timeout 超时时间（秒）
     * @return OkHttpClient实例
     */
    private static OkHttpClient getClient(int timeout) {
        if (client == null) {
            synchronized (HttpUtils.class) {
                if (client == null) {
                    client = new OkHttpClient.Builder()
                            .connectTimeout(timeout, TimeUnit.SECONDS)
                            .readTimeout(timeout, TimeUnit.SECONDS)
                            .writeTimeout(timeout, TimeUnit.SECONDS)
                            .build();
                }
            }
        }
        return client;
    }
    
    /**
     * 创建带有自定义超时的OkHttpClient实例
     * 
     * @param timeout 超时时间（秒）
     * @return OkHttpClient实例
     */
    private static OkHttpClient createCustomTimeoutClient(int timeout) {
        return new OkHttpClient.Builder()
                .connectTimeout(timeout, TimeUnit.SECONDS)
                .readTimeout(timeout, TimeUnit.SECONDS)
                .writeTimeout(timeout, TimeUnit.SECONDS)
                .build();
    }
    
    /**
     * 发送GET请求
     * 
     * @param url 请求URL
     * @return 响应字符串
     */
    public static String get(String url) {
        return get(url, null, DEFAULT_TIMEOUT);
    }
    
    /**
     * 发送带有自定义超时的GET请求
     * 
     * @param url 请求URL
     * @param timeout 超时时间（秒）
     * @return 响应字符串
     */
    public static String get(String url, int timeout) {
        return get(url, null, timeout);
    }
    
    /**
     * 发送带有请求头和自定义超时的GET请求
     * 
     * @param url 请求URL
     * @param headers 请求头
     * @param timeout 超时时间（秒）
     * @return 响应字符串
     */
    public static String get(String url, Map<String, String> headers, int timeout) {
        OkHttpClient httpClient = createCustomTimeoutClient(timeout);
        
        Request.Builder builder = new Request.Builder().url(url);
        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            headers.forEach(builder::addHeader);
        }
        
        Request request = builder.build();
        
        try (Response response = httpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                log.error("HTTP GET请求失败: {}, 状态码: {}", url, response.code());
                return null;
            }
            
            ResponseBody body = response.body();
            return body == null ? null : body.string();
        } catch (IOException e) {
            log.error("HTTP GET请求异常: {}", url, e);
            return null;
        }

    }
    
    /**
     * 发送POST请求（JSON格式）
     * 
     * @param url 请求URL
     * @param json JSON字符串
     * @return 响应字符串
     */
    public static String postJson(String url, String json) {
        return postJson(url, json, null, DEFAULT_TIMEOUT);
    }
    
    /**
     * 发送带有自定义超时的POST请求（JSON格式）
     * 
     * @param url 请求URL
     * @param json JSON字符串
     * @param timeout 超时时间（秒）
     * @return 响应字符串
     */
    public static String postJson(String url, String json, int timeout) {
        return postJson(url, json, null, timeout);
    }
    
    /**
     * 发送带有请求头和自定义超时的POST请求（JSON格式）
     * 
     * @param url 请求URL
     * @param json JSON字符串
     * @param headers 请求头
     * @param timeout 超时时间（秒）
     * @return 响应字符串
     */
    public static String postJson(String url, String json, Map<String, String> headers, int timeout) {
        OkHttpClient httpClient = createCustomTimeoutClient(timeout);
        
        RequestBody body = RequestBody.create(json, JSON);
        Request.Builder builder = new Request.Builder().url(url).post(body);
        
        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            headers.forEach(builder::addHeader);
        }
        
        Request request = builder.build();
        
        try (Response response = httpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                log.error("HTTP POST请求失败: {}, 状态码: {}", url, response.code());
                return null;
            }
            
            ResponseBody responseBody = response.body();
            return responseBody == null ? null : responseBody.string();
        } catch (IOException e) {
            log.error("HTTP POST请求异常: {}", url, e);
            return null;
        }
    }
    
    /**
     * 发送POST表单请求
     * 
     * @param url 请求URL
     * @param formParams 表单参数
     * @return 响应字符串
     */
    public static String postForm(String url, Map<String, String> formParams) {
        return postForm(url, formParams, null, DEFAULT_TIMEOUT);
    }
    
    /**
     * 发送带有自定义超时的POST表单请求
     * 
     * @param url 请求URL
     * @param formParams 表单参数
     * @param timeout 超时时间（秒）
     * @return 响应字符串
     */
    public static String postForm(String url, Map<String, String> formParams, int timeout) {
        return postForm(url, formParams, null, timeout);
    }
    
    /**
     * 发送带有请求头和自定义超时的POST表单请求
     * 
     * @param url 请求URL
     * @param formParams 表单参数
     * @param headers 请求头
     * @param timeout 超时时间（秒）
     * @return 响应字符串
     */
    public static String postForm(String url, Map<String, String> formParams, Map<String, String> headers, int timeout) {
        OkHttpClient httpClient = createCustomTimeoutClient(timeout);
        
        FormBody.Builder formBuilder = new FormBody.Builder();
        // 添加表单参数
        if (formParams != null && !formParams.isEmpty()) {
            formParams.forEach((key, value) -> {
                if (StringUtils.hasText(key) && value != null) {
                    formBuilder.add(key, value);
                }
            });
        }
        
        RequestBody body = formBuilder.build();
        Request.Builder builder = new Request.Builder().url(url).post(body);
        
        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            headers.forEach(builder::addHeader);
        }
        
        Request request = builder.build();
        
        try (Response response = httpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                log.error("HTTP POST表单请求失败: {}, 状态码: {}", url, response.code());
                return null;
            }
            
            ResponseBody responseBody = response.body();
            return responseBody == null ? null : responseBody.string();
        } catch (IOException e) {
            log.error("HTTP POST表单请求异常: {}", url, e);
            return null;
        }
    }
    
    /**
     * 异步发送GET请求
     * 
     * @param url 请求URL
     * @param callback 回调函数
     */
    public static void getAsync(String url, Callback callback) {
        getAsync(url, null, DEFAULT_TIMEOUT, callback);
    }
    
    /**
     * 异步发送带有自定义超时的GET请求
     * 
     * @param url 请求URL
     * @param timeout 超时时间（秒）
     * @param callback 回调函数
     */
    public static void getAsync(String url, int timeout, Callback callback) {
        getAsync(url, null, timeout, callback);
    }
    
    /**
     * 异步发送带有请求头和自定义超时的GET请求
     * 
     * @param url 请求URL
     * @param headers 请求头
     * @param timeout 超时时间（秒）
     * @param callback 回调函数
     */
    public static void getAsync(String url, Map<String, String> headers, int timeout, Callback callback) {
        OkHttpClient httpClient = createCustomTimeoutClient(timeout);
        
        Request.Builder builder = new Request.Builder().url(url);
        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            headers.forEach(builder::addHeader);
        }
        
        Request request = builder.build();
        httpClient.newCall(request).enqueue(callback);
    }
    
    /**
     * 异步发送POST请求（JSON格式）
     * 
     * @param url 请求URL
     * @param json JSON字符串
     * @param callback 回调函数
     */
    public static void postJsonAsync(String url, String json, Callback callback) {
        postJsonAsync(url, json, null, DEFAULT_TIMEOUT, callback);
    }
    
    /**
     * 异步发送带有自定义超时的POST请求（JSON格式）
     * 
     * @param url 请求URL
     * @param json JSON字符串
     * @param timeout 超时时间（秒）
     * @param callback 回调函数
     */
    public static void postJsonAsync(String url, String json, int timeout, Callback callback) {
        postJsonAsync(url, json, null, timeout, callback);
    }
    
    /**
     * 异步发送带有请求头和自定义超时的POST请求（JSON格式）
     * 
     * @param url 请求URL
     * @param json JSON字符串
     * @param headers 请求头
     * @param timeout 超时时间（秒）
     * @param callback 回调函数
     */
    public static void postJsonAsync(String url, String json, Map<String, String> headers, int timeout, Callback callback) {
        OkHttpClient httpClient = createCustomTimeoutClient(timeout);
        
        RequestBody body = RequestBody.create(json, JSON);
        Request.Builder builder = new Request.Builder().url(url).post(body);
        
        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            headers.forEach(builder::addHeader);
        }
        
        Request request = builder.build();
        httpClient.newCall(request).enqueue(callback);
    }
} 